/*Download*/

#include "threadPool.h"

// 发送文件
int transFile(int netfd, const char *filename, off_t offset)
{
    train_t train;
    int fd = open(filename, O_RDWR);
    lseek(fd, offset, SEEK_SET);
    struct stat statbuf;
    // 获取文件大小
    fstat(fd, &statbuf);
    // 发送小火车 火车头 size的长度 火车车厢 size的内容
    bzero(&train, sizeof(train));
    train.length = sizeof(statbuf.st_size);
    off_t realSize = statbuf.st_size - offset;
    memcpy(train.data, &realSize, train.length);
    send(netfd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);

    if (statbuf.st_size > 100 * 1024 * 1024)
    {
        // 如果文件大于100M，使用mmap
        char *p = (char *)mmap(NULL, statbuf.st_size - offset, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        ERROR_CHECK(p, MAP_FAILED, "mmap");
        off_t totalsize = 0; // 记录已经发送的长度
        while (totalsize < statbuf.st_size)
        {
            if (statbuf.st_size - totalsize > (long)sizeof(train.data))
            {
                train.length = sizeof(train.data); // 剩余数据超过火车车厢的上限
            }
            else
            {
                train.length = statbuf.st_size - totalsize;
            }
            send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
            send(netfd, p + totalsize, train.length, MSG_NOSIGNAL);
            totalsize += train.length;
        }
        munmap(p, statbuf.st_size);
    }
    else
    {
        // 小于100M，普通发送
        while (1)
        {
            // 将文件的数据读取到小火车的车厢部分
            ssize_t sret = read(fd, train.data, sizeof(train.data));
            train.length = sret;
            // 发送小火车
            send(netfd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);
            if (sret == 0)
            {
                break;
            }
        }
    }
    // 补发一个空火车
    train.length = 0;
    send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    close(fd);
    return 0;
}
